﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Continuum.Classes;

namespace Continuum
{
    public partial class EditActors : Form
    {
        private enum CurrentFormStateEnum { View, Add, Edit };
        private CurrentFormStateEnum CurrentFormState;
        Actor CurrentActor = null;

        public EditActors()
        {
            InitializeComponent();
        }

        private void EditActors_Load(object sender, EventArgs e)
        {
            foreach (Fund fund in MainForm.projector.Funds)
            {
                ddlFundPrimary.Items.Add(fund.Name);
                ddlFundSecondary.Items.Add(fund.Name);
            }

            lstActors.DataSource = MainForm.projector.Actors;

            ddlFundSecondary.Items.Add("");

            // Warn if no Funds are available for Actors to Reference
            if (MainForm.projector.Funds.Count == 0)
            {
                MessageBox.Show("Please create some Fund(s) before creating any Actors", "Unable to create an actor if you have no funds.", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }

        }

        private void SetFormState(CurrentFormStateEnum NewFormState)
        {
            CurrentFormState = NewFormState;

            if (NewFormState == CurrentFormStateEnum.Add)
            {
                chkDisabled.Enabled = true;
                txtActorName.Enabled = true;
                ddlFundPrimary.Enabled = true;
                ddlFundSecondary.Enabled = true;
                numPeriodicityUnits.Enabled = true;

                dtpInitialTriggerDate.Enabled = true;
                txtTriggerAmount.Enabled = true;
                chkTriggerEnds.Enabled = true;
                dtpTriggerEnd.Enabled = false;

                chkCompoundedInterest.Enabled = true;
                if (chkCompoundedInterest.Checked)
                {
                    txtCompIntAPR.Enabled = true;
                }

                chkIsLoanPayment.Enabled = true;
                txtAPR.Enabled = true;
                numLoanDuration.Enabled = true;
                rbDays.Enabled = true;
                rbMonths.Enabled = true;
                rbOnceOnly.Enabled = true;
                rbWeeks.Enabled = true;
                rbYears.Enabled = true;
            }

            if (NewFormState == CurrentFormStateEnum.Edit)
            {
                chkDisabled.Enabled = true;
                txtActorName.Enabled = true;
                ddlFundPrimary.Enabled = true;
                numPeriodicityUnits.Enabled = true;

                dtpInitialTriggerDate.Enabled = true;
                chkTriggerEnds.Enabled = true;
                dtpTriggerEnd.Enabled = chkTriggerEnds.Checked;

                chkCompoundedInterest.Enabled = true;
                txtCompIntAPR.Enabled = chkCompoundedInterest.Checked;

                rbDays.Enabled = !chkCompoundedInterest.Checked;
                rbWeeks.Enabled = !chkCompoundedInterest.Checked;
                rbMonths.Enabled = true;
                rbOnceOnly.Enabled = !chkCompoundedInterest.Checked;
                rbYears.Enabled = !chkCompoundedInterest.Checked;
                ddlFundSecondary.Enabled = !chkCompoundedInterest.Checked;
                txtTriggerAmount.Enabled = !chkCompoundedInterest.Checked;
                txtAPR.Enabled = !chkCompoundedInterest.Checked;
                numLoanDuration.Enabled = !chkCompoundedInterest.Checked;

                chkIsLoanPayment.Enabled = true;
            }

            if (NewFormState == CurrentFormStateEnum.View)
            {
                chkDisabled.Enabled = false;
                txtActorName.Enabled = false;
                ddlFundPrimary.Enabled = false;
                ddlFundSecondary.Enabled = false;
                numPeriodicityUnits.Enabled = false;

                dtpInitialTriggerDate.Enabled = false;
                txtTriggerAmount.Enabled = false;
                chkTriggerEnds.Enabled = false;
                dtpTriggerEnd.Enabled = false;

                chkCompoundedInterest.Enabled = false;
                txtCompIntAPR.Enabled = false;

                chkIsLoanPayment.Enabled = false;
                txtAPR.Enabled = false;
                numLoanDuration.Enabled = false;
                rbDays.Enabled = false;
                rbMonths.Enabled = false;
                rbOnceOnly.Enabled = false;
                rbWeeks.Enabled = false;
                rbYears.Enabled = false;
            }

        }

        private void ClearForm()
        {
            CurrentActor = null;

            chkDisabled.Checked = false;
            txtActorName.Text = "";
            if (ddlFundPrimary.Items.Count > 0) ddlFundPrimary.SelectedIndex = 0;
            ddlFundSecondary.Text = "";

            rbWeeks.Checked = true;
            numPeriodicityUnits.Value = 1m;

            dtpInitialTriggerDate.Value = DateTime.Now.Date;
            chkTriggerEnds.Checked = false;
            dtpTriggerEnd.Value = DateTime.Now.Date;

            txtTriggerAmount.Text = "0.0";
            chkIsLoanPayment.Checked = false;
            txtAPR.Text = "0.00";

            chkCompoundedInterest.Checked = false;
            txtCompIntAPR.Text = "0.00";

            numLoanDuration.Value = 15m;
        }

        private bool ValidateActor()
        {
            string Errors = "";

            txtActorName.Text = txtActorName.Text.Trim();
            if (txtActorName.Text == "" || txtActorName.Text == "New Actor") Errors += "Actor Name needs to be set\r\n";

            if (ddlFundPrimary.SelectedItem == null) Errors += "Primary Fund is not valid\r\n";
            if (numPeriodicityUnits.Value <= 0m) Errors += "Periodicity units needs to be a positive integer\r\n";
            try
            {
                Decimal trigamt = Decimal.Parse(txtTriggerAmount.Text);
                if (!chkCompoundedInterest.Checked && trigamt == 0.0m) Errors += "Trigger Amount needs to be non-zero\r\n";
            }
            catch { Errors += "Trigger Amount is not a valid number\r\n"; }

            try { Decimal apr = Decimal.Parse(txtAPR.Text); }
            catch { Errors += "APR is not a valid number\r\n"; }

            if (chkIsLoanPayment.Checked && numLoanDuration.Value <= 0) Errors += "Loan Duration needs to be a positive integer\r\n";

            if (Errors.Length > 0)
            {
                MessageBox.Show("Please correct the following errors : \r\n" + Errors, "Unable to save due to Validation Errors", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return false;
            }

            return true;
        }

        #region ListIndex Change Events

        private void lstActors_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstActors.SelectedItem == null) return;

            Actor actor = (Actor)lstActors.SelectedItem;
            CurrentActor = actor;

            chkDisabled.Checked = actor.IsDisabled;
            txtActorName.Text = actor.ActorName;
            ddlFundPrimary.Text = actor.ActorFundPrimary;
            ddlFundSecondary.Text = actor.ActorFundSecondary;
            switch (actor.ActorPeriodicity)
            {
                case ActorPeriodicityEnum.Daily: rbDays.Checked = true; break;
                case ActorPeriodicityEnum.Weekly: rbWeeks.Checked = true; break;
                case ActorPeriodicityEnum.Monthly: rbMonths.Checked = true; break;
                case ActorPeriodicityEnum.Yearly: rbYears.Checked = true; break;
                case ActorPeriodicityEnum.OnceOnly: rbOnceOnly.Checked = true; break;
                default: rbWeeks.Checked = true; break;
            }
            numPeriodicityUnits.Value = (Decimal) actor.ActorPeriodicityUnits;

            dtpInitialTriggerDate.Value = actor.TriggerDateInitial;
            txtTriggerAmount.Text = actor.TriggerAmount.ToString();

            dtpTriggerEnd.Value = DateTime.Now.Date;
            if (actor.TriggerDateEnd == DateTime.MaxValue)
            {
                chkTriggerEnds.Checked = false;
            }
            else
            {
                dtpTriggerEnd.Value = actor.TriggerDateEnd;
                chkTriggerEnds.Checked = true;
            }

            if (actor.IsCompoundInterestAccrual)
            {
                chkCompoundedInterest.Checked = true;
                txtCompIntAPR.Text = actor.CompoundInterestRate.ToString();
            }
            else
            {
                chkCompoundedInterest.Checked = false;
                txtCompIntAPR.Text = "0.00";
            }

            chkIsLoanPayment.Checked = actor.IsLoanPayment;
            txtAPR.Text = actor.InterestRate.ToString();
            numLoanDuration.Value = (Decimal) actor.LoanDurationInYears;

            SetFormState(CurrentFormStateEnum.View);
        }

        #endregion

        #region Button Handlers

        private void btnNew_Click(object sender, EventArgs e)
        {
            ClearForm();
            SetFormState(CurrentFormStateEnum.Add);
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            Actor actor;

            if (CurrentFormState == CurrentFormStateEnum.Add)
            {
                actor = new Actor();
            }
            else
            {
                actor = (Actor) lstActors.SelectedItem;
            }

            if (!ValidateActor()) return;

            actor.IsDisabled = chkDisabled.Checked;
            actor.ActorName = txtActorName.Text;
            actor.ActorFundPrimary = ddlFundPrimary.Text;
            actor.ActorFundSecondary = ddlFundSecondary.Text;
            if (rbDays.Checked) actor.ActorPeriodicity = ActorPeriodicityEnum.Daily;
            if (rbWeeks.Checked) actor.ActorPeriodicity = ActorPeriodicityEnum.Weekly;
            if (rbMonths.Checked) actor.ActorPeriodicity = ActorPeriodicityEnum.Monthly;
            if (rbYears.Checked) actor.ActorPeriodicity = ActorPeriodicityEnum.Yearly;
            if (rbOnceOnly.Checked) actor.ActorPeriodicity = ActorPeriodicityEnum.OnceOnly;
            actor.ActorPeriodicityUnits = (int)numPeriodicityUnits.Value;
            actor.TriggerDateInitial = dtpInitialTriggerDate.Value.Date;
            actor.TriggerAmount = Decimal.Parse(txtTriggerAmount.Text);

            if (chkTriggerEnds.Checked) actor.TriggerDateEnd = dtpTriggerEnd.Value.Date;
            else actor.TriggerDateEnd = DateTime.MaxValue;

            if (chkCompoundedInterest.Checked)
            {
                actor.IsCompoundInterestAccrual = true;
                actor.CompoundInterestRate = Decimal.Parse(txtCompIntAPR.Text);
            }

            actor.IsLoanPayment = chkIsLoanPayment.Checked;
            actor.InterestRate = Decimal.Parse(txtAPR.Text);
            actor.LoanDurationInYears = (int)numLoanDuration.Value;

            if (CurrentActor == null) { MainForm.projector.Actors.Add(actor); }
            else { CurrentActor = null; }

            // Rebind/Refresh
            lstActors.DataSource = null;
            lstActors.DataSource = MainForm.projector.Actors;

            MainForm.InstanceRef.HasChanged = true;
        }

        private void btnEdit_Click(object sender, EventArgs e)
        {
            SetFormState(CurrentFormStateEnum.Edit);
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (lstActors.SelectedItem == null) return;

            if (MessageBox.Show("Are you sure you want to delete this Actor?", "Confirm Actor Deletion", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK) return;

            Actor actor = (Actor)lstActors.SelectedItem;

            MainForm.projector.Actors.Remove(actor);

            // Rebind/Refresh
            lstActors.DataSource = null;
            lstActors.DataSource = MainForm.projector.Actors;

            MainForm.InstanceRef.HasChanged = true;
        }

        private void btnDone_Click(object sender, EventArgs e)
        {
            Close();
        }

        #endregion

        #region Simple Numeric Textbox Filtering

        private void txtTriggerAmount_KeyDown(object sender, KeyEventArgs e)
        {
            if (!(e.KeyValue >= '0' && e.KeyValue <= '9') && !(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
                && e.KeyCode != Keys.Decimal && e.KeyCode != Keys.Back && e.KeyCode != Keys.OemPeriod
                && e.KeyCode != Keys.Delete && e.KeyCode != Keys.Insert && e.KeyCode != Keys.OemMinus && e.KeyCode != Keys.Subtract
               ) e.SuppressKeyPress = true;
        }

        private void txtAPR_KeyDown(object sender, KeyEventArgs e)
        {
            if (!(e.KeyValue >= '0' && e.KeyValue <= '9') && !(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
                && e.KeyCode != Keys.Decimal && e.KeyCode != Keys.Back && e.KeyCode != Keys.OemPeriod
                && e.KeyCode != Keys.Delete && e.KeyCode != Keys.Insert
               ) e.SuppressKeyPress = true;
        }

        #endregion

        #region FormState Manangement (IsLoan, IsAccrual, TriggerEnds)

        private void chkTriggerEnds_CheckedChanged(object sender, EventArgs e)
        {
            if (CurrentFormState != CurrentFormStateEnum.View)
            {
                dtpTriggerEnd.Enabled = chkTriggerEnds.Checked;
            }
        }

        private void chkCompoundedInterest_CheckedChanged(object sender, EventArgs e)
        {
            if (CurrentFormState != CurrentFormStateEnum.View)
            {
                txtCompIntAPR.Enabled = chkCompoundedInterest.Checked;
                rbDays.Enabled = !chkCompoundedInterest.Checked;
                rbWeeks.Enabled = !chkCompoundedInterest.Checked;
                rbOnceOnly.Enabled = !chkCompoundedInterest.Checked;
                rbYears.Enabled = !chkCompoundedInterest.Checked;
                ddlFundSecondary.Enabled = !chkCompoundedInterest.Checked;
                txtTriggerAmount.Enabled = !chkCompoundedInterest.Checked;
                txtAPR.Enabled = !chkCompoundedInterest.Checked;
                numLoanDuration.Enabled = !chkCompoundedInterest.Checked;
                
                if (chkCompoundedInterest.Checked)
                {
                    ddlFundSecondary.Text = "";
                    chkIsLoanPayment.Checked = false;
                    rbMonths.Checked = true;
                }
            }
        }

        private void chkIsLoanPayment_CheckedChanged(object sender, EventArgs e)
        {
            if (CurrentFormState != CurrentFormStateEnum.View)
            {
                txtAPR.Enabled = chkIsLoanPayment.Checked;
                numLoanDuration.Enabled = chkIsLoanPayment.Checked;

                if (chkIsLoanPayment.Checked) chkCompoundedInterest.Checked = false;
            }
        }

        #endregion

        private void lnkOnlineHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo.UseShellExecute = true;
            proc.StartInfo.FileName = "http://project-continuum.com/OnlineHelp/AdvancedActors.aspx";
            proc.Start();
        }

    }
}
